
#include "Logic/SkeletalInstancedSubsystem.h"

#include "SkelotAnimCollection.h"
#include "Logic/SkeletalInstanceManagerActor.h"

USkeletalInstancedSubsystem* USkeletalInstancedSubsystem::Get(const UObject* WorldContext)
{
	return WorldContext->GetWorld()->GetSubsystem<USkeletalInstancedSubsystem>();
}

void USkeletalInstancedSubsystem::Register(FSkeletalInstancedProxyAbstract* Proxy)
{
	ProxySet.Add(Proxy);
}

void USkeletalInstancedSubsystem::UnRegister(FSkeletalInstancedProxyAbstract* Proxy)
{
	ProxySet.Remove(Proxy);
}

ASlgSkeletalInstanceActor* USkeletalInstancedSubsystem::GetInstancedBatchActor()
{
	if(InstancedBatchActor)
	{
		return InstancedBatchActor;
	}
	if(UWorld* World = GetWorld() )
	{
		//if(World->HasBegunPlay())
		{
			InstancedBatchActor = World->SpawnActor<ASlgSkeletalInstanceActor>();
			InstancedBatchActor->SetComponentClass( SkelotComponentSoftClassPath.TryLoadClass<USkelotComponent>() );
			return InstancedBatchActor;
		}
	}
	return nullptr;
}

USkelotComponent* USkeletalInstancedSubsystem::FindComponent(FSkeletalInstancedProxyAbstract* Proxy)
{
	if (auto Actor = GetInstancedBatchActor())
	{
		return Actor->FindComponent(Proxy);
	}
	return nullptr;
}

USkelotAnimCollection* USkeletalInstancedSubsystem::FindAnimCollection(USkeleton* Skeleton)
{
	if(auto Value = AnimCollectionMap.Find(Skeleton))
	{
		return *Value;
	}
	return CreateAnimCollection(Skeleton);
}

//void USlgSkeletalInstancedSubsystem::OnInitialize()
//{
//	Super::OnInitialize();
//
//	InitializeAnimCollection();
//}

void USkeletalInstancedSubsystem::InitializeAnimCollection()
{
	if(!AnimCollectionMap.IsEmpty())
	{
		return;
	}
	for(const auto& Value : AnimCollectionSoftObjectPaths)
	{
		UObject* Object = Value.TryLoad();
		if(!Object)
		{
			UE_LOG(LogTemp, Warning, TEXT("USlgSkeletalInstancedSubsystem::InitializeAnimCollection Error %s"), *Value.ToString());
			continue;
		}
		USkelotAnimCollection* AnimCollection = Cast<USkelotAnimCollection>(Object);
		if(!AnimCollection)
		{
			UE_LOG(LogTemp, Warning, TEXT("USlgSkeletalInstancedSubsystem::InitializeAnimCollection ErrorType %s"), *Value.ToString());
			continue;
		}
		if(!AnimCollection->Skeleton)
		{
			UE_LOG(LogTemp, Warning, TEXT("USlgSkeletalInstancedSubsystem::InitializeAnimCollection ErrorSkeleton %s"), *Value.ToString());
			continue;
		}
		AnimCollectionMap.Add(AnimCollection->Skeleton, AnimCollection);
	}
}

USkelotAnimCollection* USkeletalInstancedSubsystem::CreateAnimCollection(USkeleton* Skeleton)
{
	USkelotAnimCollection* AnimCollection = NewObject<USkelotAnimCollection>(this);
	AnimCollection->Skeleton = Skeleton;
	return AnimCollection;
}